package com.jinlia.show.modules.base.wxapp.service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jinlia.show.modules.base.constant.CouponStatusEnum;
import com.jinlia.show.modules.base.model.po.UserCouponRelPO;
import com.jinlia.show.modules.base.model.query.UserCouponQuery;
import com.jinlia.show.modules.base.system.entity.Coupon;
import com.jinlia.show.modules.base.system.service.CouponMapperService;
import com.jinlia.show.modules.base.wxapp.entity.UserCouponRel;
import com.jinlia.show.modules.base.wxapp.mapper.UserCouponRelMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.util.List;
import java.util.Objects;

@Slf4j
@Service
public class UserCouponRelMapperService extends ServiceImpl<UserCouponRelMapper, UserCouponRel> {
    @Autowired
    private CouponMapperService couponMapperService;


    public List<UserCouponRelPO> selectList(UserCouponQuery userCouponQuery) {
        List<UserCouponRelPO> userCouponRelPOS = this.baseMapper.selectListPO(userCouponQuery);
        userCouponRelPOS.forEach(item -> fillCouponStatus(item, LocalDate.now()));
        return userCouponRelPOS;
    }

    private void fillCouponStatus(UserCouponRelPO item, LocalDate now) {
        if (item.getId() == null) {
            // 未领取
            if (item.getCoupon() != null && now.isBefore(item.getCoupon().getEndDate())) {
                item.setCouponStatus(CouponStatusEnum.A.getLabel());
            } else {
                item.setCouponStatus(CouponStatusEnum.C.getLabel()); // 已失效
            }
        } else {
            // 已领取
            if (item.getUsedTime() != null) {
                item.setCouponStatus(CouponStatusEnum.D.getLabel()); // 已使用
            } else if (item.getValidDateTo() != null && !item.getValidDateTo().isBefore(now)) {
                item.setCouponStatus(CouponStatusEnum.B.getLabel()); // 待使用
            } else {
                item.setCouponStatus(CouponStatusEnum.C.getLabel()); // 已失效
            }
        }
    }

    @Transactional
    public UserCouponRel receiveCoupon(UserCouponRel userCouponRel) {
        Coupon byIdCoupon = couponMapperService.getById(userCouponRel.getCouponId());
        Integer validDate = byIdCoupon.getValidDate();
        userCouponRel.setValidDateTo(LocalDate.now().plusDays(validDate));
        this.save(userCouponRel);
        boolean update = couponMapperService.lambdaUpdate()
                .eq(Coupon::getId, userCouponRel.getCouponId())
                .eq(Coupon::getReleasedAmount, byIdCoupon.getReleasedAmount())//乐观锁
                .set(Coupon::getReleasedAmount, byIdCoupon.getReleasedAmount() + 1)
                .update();
        if (!update) {
            throw new RuntimeException("领取失败");
        }
        return userCouponRel;
    }
}
